package com.cms.autocode;

import java.io.File;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.sql.DataSource;

import org.apache.commons.io.FileUtils;

import com.jfinal.kit.PathKit;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.template.Engine;

public class AutoCode {
    
   //输出地址
   public static final String outFilePath ="c:/autocode";
	
	//模板地址
	public static final String autoCodePath = PathKit.getWebRootPath()+"/src/main/resources/autocode";
	public static final String templatePath = autoCodePath+"/template";
	public static final String viewCreatePath = autoCodePath+"/view";
	public static final String javaCreatePath = autoCodePath+"/java";
	
	//包名
	public static String packageName = "com.cms.controller.admin";
	//不包含字段名
	public static String [] excludeNames = new String[]{"id","createDate","modifyDate"};
	//表名
	public static String tablePrefix = "cms_";
	public static String [] tableNames = new String[]{"cms_admin|管理员"};
	//模板页面
	public static String [] viewNames = new String[]{"add.html","edit.html","list.html"};
	
	public static void main(String[] args) throws Exception{
	    File outFile = new File(outFilePath);
	    if(!outFile.exists()){
	        outFile.mkdir();
	    }
	    Connection connection = getDataSource().getConnection();
	    Statement statement = connection.createStatement();
	    for(String tableItem : tableNames){
	        String [] tableItems  = tableItem.split("\\|");
	        String tableName = tableItems[0];
	        String userName = tableItems[1];
	        String objectName = getHumpName(tableName.replace(tablePrefix, ""));
	        String className = getHumpName("_"+tableName.replace(tablePrefix, ""));
	        AutoClass autoClass = new AutoClass();
	        autoClass.setPackageName(packageName);
	        autoClass.setClassName(className);
	        autoClass.setUseName(userName);
	        autoClass.setPathName(tableName.replace("cms_", ""));
	        autoClass.setObjectName(objectName);
	        List<AutoField> fields = new ArrayList<>();
	        ResultSet columnsResultSet = statement.executeQuery("show full columns from "+tableName+";");
	        while(columnsResultSet.next()){
	            String columnName = columnsResultSet.getString(1);
	            String columnType = columnsResultSet.getString(2);
	            String columnNull = columnsResultSet.getString(4);
	            String columnComment = columnsResultSet.getString(9);
	            if(Arrays.asList(excludeNames).contains(columnName)){
	                continue;
	            }
	            AutoField autoField = new AutoField();
	            autoField.setName(columnName);
	            autoField.setTitle(columnComment);
	            if("YES".equals(columnNull)){
	                autoField.setIsRequired(false);
	            }else{
	                autoField.setIsRequired(true);
	            }
	            if(columnType.startsWith("varchar(")){
	                autoField.setType("text");
	            }else if(columnType.equals("longtext")){
                    autoField.setType("editor");
                }else if(columnType.equals("text")){
                    autoField.setType("textarea");
                }
	            fields.add(autoField);
	        }
	        autoClass.setFields(fields);
	        Map<String,Object> model = objToMap(autoClass);
	        File actionFile = new File(templatePath+"/action.html");
	        String actionFileContent = FileUtils.readFileToString(actionFile);
	        String actionCode =Engine.use().getTemplateByString(actionFileContent).renderToString(model);
	        String actionCodePath = outFilePath+"/"+autoClass.getPackageName().replace(".", "/")+"/"+autoClass.getClassName()+"Controller.java";
	        FileUtils.write(new File(actionCodePath), actionCode);
	        for(String viewName : viewNames){
	            File viewFile = new File(templatePath+"/"+viewName);
	            String viewFileContent = FileUtils.readFileToString(viewFile);
	            String viewCode = Engine.use().getTemplateByString(viewFileContent).renderToString(model);
	            String viewCodePath = outFilePath+"/"+viewName;
	            FileUtils.write(new File(viewCodePath), viewCode);
	        }
	    }
	    statement.close();
	    connection.close();
	}
	
	
	//对象转化成map
    public static Map<String, Object> objToMap(Object obj){
        Map<String, Object> dataBaseMap = new HashMap<String, Object>();
        // 获取属性
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object o = field.get(obj);
                if (o == null) {
                    continue;
                }
                dataBaseMap.put(field.getName(), o);
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
        return dataBaseMap;
    }
    
    //获取驼峰式命名
    public static String getHumpName(String str){
        str = str.toLowerCase();
        StringBuffer sb = new StringBuffer();
        Pattern p = Pattern.compile("_(\\w)");
        Matcher m = p.matcher(str);
        while (m.find()){
            m.appendReplacement(sb,m.group(1).toUpperCase());
        }
        m.appendTail(sb);
        return sb.toString();
    }

    //数据源
   public static DataSource getDataSource() {
        PropKit.use("config.properties");
        DruidPlugin druidPlugin = new DruidPlugin(PropKit.get("jdbc.url"), PropKit.get("jdbc.username"), PropKit.get("jdbc.password"),PropKit.get("jdbc.driver"));
        druidPlugin.start();
        return druidPlugin.getDataSource();
    }
   
}
